上一篇介紹了三個工具和 DeFiHackLabs,今天開始實際跑,先從最容易上手的 Slither 開始。案例從 DeFiHackLabs 挑了一個很小的,受害合約只有一個檔案,漏洞也只有一行。
Slither 是 Trail of Bits 用 Python 寫的開源靜態分析工具。它不會執行合約,會先把 Solidity 編譯,再轉成自己的中間表示,讓偵測器 (detector) 在上面找特定的程式結構。
我用的版本是 Slither 0.11.6,內建 102 個偵測器。安裝只要一行:
python3 -m pip install slither-analyzer
Slither 本身不含 Solidity 編譯器,要另外裝合約對應版本的 solc,可以用同一個團隊做的 solc-select 安裝和切換版本。
FlippazOne 是以太坊上的一個 NFT 拍賣合約,整個合約只會鑄造一個 NFT(MAX_SUPPLY = 1)。拍賣由 owner 開始,任何人都能出價,出價的 ETH 會先存在合約裡,拍賣結束後由 owner 提走得標金額。
2022 年 7 月 6 日,有人呼叫合約的 ownerWithdrawAllTo,傳入自己的地址,把合約裡的 ETH 全部轉走了:
function ownerWithdrawAllTo(address toAddress) public {
(bool success, ) = toAddress.call{value: address(this).balance}("");
require(success, "Failed to withdraw funds.");
}
函式名稱有 owner,但沒有加 onlyOwner,也沒有其他檢查,所以任何人都能呼叫。同一個合約裡的 editBaseUri、startAuction 都有加 onlyOwner,但四個名稱開頭是 owner 的提款函式都沒有加。
合約原始碼可以在 Sourcify 下載驗證過的版本,編譯器是 0.8.15。檔案有 1397 行,大部分是一起攤平進來的 OpenZeppelin,FlippazOne 本身大約 240 行。
solc-select install 0.8.15
solc-select use 0.8.15
slither FlippazOne.sol
Slither 會先呼叫 solc 編譯,再讓每個偵測器檢查一遍。輸出的最後一行是總數:

每個偵測器都有 Impact 和 Confidence 兩個分級。Impact 是問題如果成立,影響有多大;Confidence 是偵測器對這個判斷有多確定。終端機上看不到這兩個欄位,加上 --json result.json 輸出成 JSON 就能看到每個結果的分級。40 個結果依 Impact 分:
| Impact | 數量 |
|---|---|
| High | 5 |
| Medium | 1 |
| Low | 15 |
| Informational | 18 |
| Optimization | 1 |
在終端機上,Impact 是用顏色區分的:紅色是 High,黃色是 Medium,綠色是 Low、Informational 和 Optimization。

5 個 High 裡,有一個就是這次事件的根因。
arbitrary-send-eth
arbitrary-send-eth 底下的第二個結果就是 ownerWithdrawAllTo,括號裡的 #1359-1362 是函式所在的行號,Dangerous calls 底下列的是轉出 ETH 的那一行。
這個偵測器找的是:函式會把 ETH 送到呼叫者可以決定的地址,而且函式本身沒有權限保護。toAddress 是呼叫者傳進來的參數,函式也沒有保護,所以被標成 High。
40 個結果裡,只有這一個對應到實際被攻擊的漏洞。其他 4 個 High 包含另一個提款函式、重入結構和沒有初始化的變數;Low 和 Informational 則多半是使用 block.timestamp、低階呼叫這類提醒。這些都要人一個一個看過,才知道要不要處理。
在這個真實的受害合約上,Slither 的 High 直接指到了事件的根因,也標出了行號。但 40 個結果裡只有一個是這次的漏洞,剩下的還是要自己判斷。
將更深入介紹 Slither 的運作流程,說明 Slither 運作的步驟與組成。